package tuanda.soict.firstsun.AbilityPackage;

import java.util.ArrayList;
import java.util.Random;

import tuanda.soict.firstsun.EffectPackage.Movement_Effect;
import tuanda.soict.firstsun.LogicPackage.Army;
import tuanda.soict.firstsun.LogicPackage.BattleMap;
import tuanda.soict.firstsun.LogicPackage.Coordinate;
import tuanda.soict.firstsun.LogicPackage.Scenario;

/**
 * @author tuanda_soict_hut
 * @version 0.0.2
 * @since 7-10-2012
 */
public class Blizzard_Ability extends Ability {

	final static int BLIZZARD_DAMAGE = 35;

	public Blizzard_Ability(int id, String name, int range, int area, int affect) {
		super(id, name, range, area, affect);
	}

	@Override
	public void mainAct(Army army, Scenario scenario) {
		int level = getAbilityLevel();
		Coordinate current = army.getCoordinate();
		int range = this.getAbilityRange();
		Coordinate targetCoor = this.getTarget();
		BattleMap map = scenario.getBattleMap();
		if (current.getDistance(targetCoor) <= range) {
			ArrayList<Coordinate> affectedArea = calculateAffectedArea(army,
					scenario);
			Random rand = new Random();
			int damage;
			for (Coordinate coor : affectedArea) {
				Army arm = map
						.getArmy(coor.getLocationX(), coor.getLocationY());
				if (arm != null) {
					damage = (rand.nextInt(10)) + BLIZZARD_DAMAGE + level * 5;
					int prevArmyHP = army.getHealth();
					int prevEnemyHP = arm.getHealth();
					damageToEnemy(army, damage, arm, false);
					if (arm.isInAttackRange(army.getLocationX(),
							army.getLocationY())) {
						Attack enemyAttack = (Attack) arm.getAttackAbility();
						enemyAttack.setTarget(current);
						enemyAttack.mainAct(arm, scenario);
						int allyRank = army.getRank();
						int armyDead = prevArmyHP - army.getHealth();
						arm.setExperience(arm.getExperience() + armyDead
								* allyRank, armyManager);
					}
					int enemyDead = prevEnemyHP - arm.getHealth();
					army.setExperience(
							army.getExperience() + enemyDead * arm.getRank(),
							armyManager);
					Movement_Effect blizzardEffect = new Movement_Effect(
							this.getID(), this.getName(), 1, -2, scenario);
					arm.addEffect(blizzardEffect);
				}
			}
		}
	}

	@Override
	public void calculation(Army army, Scenario scenario) {
		Coordinate targetCoor = this.getTarget();
		BattleMap map = scenario.getBattleMap();
		Army arm = map.getArmy(targetCoor.getLocationX(),
				targetCoor.getLocationY());
		if (arm != null) {
			int damage = BLIZZARD_DAMAGE + (getAbilityLevel() << 1);
			this.setAbilityPoint(damage * arm.getRank());
		}
	}

	@Override
	public ArrayList<Coordinate> calculateAffectedArea(Army army,
			Scenario scenario) {
		ArrayList<Coordinate> temp = new ArrayList<Coordinate>();
		Coordinate target = this.getTarget();
		int targetLocationX = target.getLocationX();
		int targetLocationY = target.getLocationY();
		if (scenario.getBattleMap().isValidCoordinate(targetLocationX,
				targetLocationY)) {
			temp.add(target);
		}
		int locationX = army.getLocationX();
		int locationY = army.getLocationY();

		if (targetLocationX == locationX) {
			int tempX1 = targetLocationX + 1;
			int tempX2 = targetLocationX - 1;
			if (scenario.getBattleMap().isValidCoordinate(tempX1,
					targetLocationY)) {
				temp.add(new Coordinate(tempX1, targetLocationY));
			}
			if (scenario.getBattleMap().isValidCoordinate(tempX2,
					targetLocationY)) {
				temp.add(new Coordinate(tempX2, targetLocationY));
			}
		} else if (targetLocationY == locationY) {
			int tempY1 = targetLocationY + 1;
			int tempY2 = targetLocationY - 1;
			if (scenario.getBattleMap().isValidCoordinate(targetLocationX,
					tempY1)) {
				temp.add(new Coordinate(targetLocationX, tempY1));
			}
			if (scenario.getBattleMap().isValidCoordinate(targetLocationX,
					tempY2)) {
				temp.add(new Coordinate(targetLocationX, tempY2));
			}
		} else {
			int deltaX = targetLocationX - locationX;
			int deltaY = targetLocationY - locationY;
			int tempY1, tempX1, tempY2, tempX2;

			if (deltaX < 0) {
				if (deltaY < 0) {
					tempY1 = targetLocationY - 1;
					tempX1 = targetLocationX + 1;

					tempY2 = targetLocationY + 1;
					tempX2 = targetLocationX - 1;
				} else {
					tempY1 = targetLocationY + 1;
					tempX1 = targetLocationX + 1;

					tempY2 = targetLocationY - 1;
					tempX2 = targetLocationX - 1;
				}
			} else {// deltaX>0
				if (deltaY < 0) {
					tempY1 = targetLocationY + 1;
					tempX1 = targetLocationX + 1;

					tempY2 = targetLocationY - 1;
					tempX2 = targetLocationX - 1;
				} else {
					tempY1 = targetLocationY - 1;
					tempX1 = targetLocationX + 1;

					tempY2 = targetLocationY + 1;
					tempX2 = targetLocationX - 1;
				}
			}

			if (scenario.getBattleMap().isValidCoordinate(tempX1, tempY1)) {
				temp.add(new Coordinate(tempX1, tempY1));
			}
			if (scenario.getBattleMap().isValidCoordinate(tempX2, tempY2)) {
				temp.add(new Coordinate(tempX2, tempY2));
			}
		}
		return temp;
	}
}
